package com.smart.community.emergency.service;

import com.smart.community.commons.base.BaseEntity;
import com.smart.community.commons.result.PageResult;
import org.springframework.cache.annotation.*;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 紧急求助Service接口
 * 提供紧急呼叫、应急处理、资源调度等相关的业务操作
 * 
 * @author Wu.Liang
 * @since 2024-12-19
 * @version 1.0.0
 */
public interface IEmergencyService {
    
    // ========================= 紧急呼叫管理 =========================
    
    /**
     * 发起紧急呼叫
     * 
     * @param emergencyCall 紧急呼叫信息
     * @return 呼叫ID
     */
    @CacheEvict(value = "emergency", key = "'pending'")
    Long createEmergencyCall(EmergencyCall emergencyCall);
    
    /**
     * 分页查询紧急呼叫
     * 
     * @param current       当前页
     * @param size          每页大小
     * @param communityId   社区ID
     * @param emergencyType 紧急类型
     * @param status        状态
     * @return 分页结果
     */
    PageResult<EmergencyCall> pageEmergencyCalls(Integer current, Integer size,
                                                Long communityId, String emergencyType, Integer status);
    
    /**
     * 根据ID查询紧急呼叫（使用缓存）
     * 
     * @param callId 呼叫ID
     * @return 紧急呼叫信息
     */
    @Cacheable(value = "emergency", key = "'call:' + #callId", unless = "#result == null")
    EmergencyCall getEmergencyCallById(Long callId);
    
    /**
     * 接受紧急呼叫
     * 
     * @param callId    呼叫ID
     * @param handlerId 处理人ID
     * @return 是否接受成功
     */
    @Caching(evict = {
        @CacheEvict(value = "emergency", key = "'call:' + #callId"),
        @CacheEvict(value = "emergency", key = "'pending'"),
        @CacheEvict(value = "emergency", key = "'processing'")
    })
    boolean acceptEmergencyCall(Long callId, Long handlerId);
    
    /**
     * 完成紧急处理
     * 
     * @param callId       呼叫ID
     * @param handleResult 处理结果
     * @return 是否完成成功
     */
    @CacheEvict(value = "emergency", allEntries = true, condition = "#handleResult != null")
    boolean completeEmergencyCall(Long callId, String handleResult);
    
    // ========================= 应急预案管理 =========================
    
    /**
     * 添加应急预案
     * 
     * @param plan 预案信息
     * @return 预案ID
     */
    @CacheEvict(value = "emergency", key = "'plans:' + #plan.emergencyType")
    Long addEmergencyPlan(EmergencyPlan plan);
    
    /**
     * 根据紧急类型查询预案
     * 
     * @param emergencyType 紧急类型
     * @return 预案列表
     */
    @Cacheable(value = "emergency", key = "'plans:' + #emergencyType", unless = "#result == null or #result.isEmpty()")
    List<EmergencyPlan> getPlansByEmergencyType(String emergencyType);
    
    /**
     * 启动应急预案
     * 
     * @param planId 预案ID
     * @param callId 呼叫ID
     * @return 是否启动成功
     */
    boolean activateEmergencyPlan(Long planId, Long callId);
    
    // ========================= 应急联系人管理 =========================
    
    /**
     * 添加应急联系人
     * 
     * @param contact 联系人信息
     * @return 联系人ID
     */
    @CacheEvict(value = "emergency", key = "'contacts:' + #contact.userId")
    Long addEmergencyContact(EmergencyContact contact);
    
    /**
     * 根据用户ID查询应急联系人
     * 
     * @param userId 用户ID
     * @return 联系人列表
     */
    @Cacheable(value = "emergency", key = "'contacts:' + #userId", unless = "#result == null or #result.isEmpty()")
    List<EmergencyContact> getEmergencyContactsByUserId(Long userId);
    
    /**
     * 批量通知应急联系人
     * 
     * @param callId 呼叫ID
     * @return 通知结果
     */
    boolean notifyEmergencyContacts(Long callId);
    
    // ========================= 应急资源管理 =========================
    
    /**
     * 添加应急资源
     * 
     * @param resource 资源信息
     * @return 资源ID
     */
    @Caching(evict = {
        @CacheEvict(value = "emergency", key = "'available_resources:' + #resource.resourceType + ':' + #resource.communityId"),
        @CacheEvict(value = "emergency", key = "'resources:' + #resource.resourceType + ':' + #resource.communityId")
    })
    Long addEmergencyResource(EmergencyResource resource);
    
    /**
     * 根据类型查询可用应急资源
     * 
     * @param resourceType 资源类型
     * @param communityId  社区ID
     * @return 资源列表
     */
    @Cacheable(value = "emergency", key = "'available_resources:' + #resourceType + ':' + #communityId", unless = "#result == null or #result.isEmpty()")
    List<EmergencyResource> getAvailableResourcesByType(String resourceType, Long communityId);
    
    /**
     * 调度应急资源
     * 
     * @param callId      紧急呼叫ID
     * @param resourceIds 资源ID列表
     * @return 是否调度成功
     */
    boolean dispatchEmergencyResources(Long callId, List<Long> resourceIds);
    
    // ========================= 统计分析 =========================
    
    /**
     * 获取紧急求助统计信息
     * 
     * @param communityId 社区ID
     * @param startTime   开始时间
     * @param endTime     结束时间
     * @return 统计信息
     */
    @Cacheable(value = "emergency", key = "'statistics:' + #communityId + ':' + #startTime.toString() + ':' + #endTime.toString()", unless = "#result == null")
    EmergencyStatistics getEmergencyStatistics(Long communityId, LocalDateTime startTime, LocalDateTime endTime);
    
    /**
     * 清除紧急求助相关缓存
     */
    @CacheEvict(value = "emergency", allEntries = true)
    void clearEmergencyCache();
    
    // ========================= 内部类定义 =========================
    
    /**
     * 紧急呼叫
     */
    class EmergencyCall extends BaseEntity {
        private String callNo;
        private Long callerId;
        private Long communityId;
        private String emergencyType;
        private String description;
        private String location;
        private BigDecimal longitude;
        private BigDecimal latitude;
        private Integer urgencyLevel;
        private Integer status;
        private Long handlerId;
        private LocalDateTime acceptTime;
        private LocalDateTime completeTime;
        private String handleResult;
        
        // getter/setter methods
        public String getCallNo() { return callNo; }
        public void setCallNo(String callNo) { this.callNo = callNo; }
        
        public Long getCallerId() { return callerId; }
        public void setCallerId(Long callerId) { this.callerId = callerId; }
        
        public Long getCommunityId() { return communityId; }
        public void setCommunityId(Long communityId) { this.communityId = communityId; }
        
        public String getEmergencyType() { return emergencyType; }
        public void setEmergencyType(String emergencyType) { this.emergencyType = emergencyType; }
        
        public String getDescription() { return description; }
        public void setDescription(String description) { this.description = description; }
        
        public String getLocation() { return location; }
        public void setLocation(String location) { this.location = location; }
        
        public BigDecimal getLongitude() { return longitude; }
        public void setLongitude(BigDecimal longitude) { this.longitude = longitude; }
        
        public BigDecimal getLatitude() { return latitude; }
        public void setLatitude(BigDecimal latitude) { this.latitude = latitude; }
        
        public Integer getUrgencyLevel() { return urgencyLevel; }
        public void setUrgencyLevel(Integer urgencyLevel) { this.urgencyLevel = urgencyLevel; }
        
        public Integer getStatus() { return status; }
        public void setStatus(Integer status) { this.status = status; }
        
        public Long getHandlerId() { return handlerId; }
        public void setHandlerId(Long handlerId) { this.handlerId = handlerId; }
        
        public LocalDateTime getAcceptTime() { return acceptTime; }
        public void setAcceptTime(LocalDateTime acceptTime) { this.acceptTime = acceptTime; }
        
        public LocalDateTime getCompleteTime() { return completeTime; }
        public void setCompleteTime(LocalDateTime completeTime) { this.completeTime = completeTime; }
        
        public String getHandleResult() { return handleResult; }
        public void setHandleResult(String handleResult) { this.handleResult = handleResult; }
    }
    
    /**
     * 应急预案
     */
    class EmergencyPlan extends BaseEntity {
        private String planCode;
        private String planName;
        private String emergencyType;
        private String planContent;
        private String procedures;
        private String resourceRequirements;
        private Integer priority;
        private Integer status;
        
        // getter/setter methods
        public String getPlanCode() { return planCode; }
        public void setPlanCode(String planCode) { this.planCode = planCode; }
        
        public String getPlanName() { return planName; }
        public void setPlanName(String planName) { this.planName = planName; }
        
        public String getEmergencyType() { return emergencyType; }
        public void setEmergencyType(String emergencyType) { this.emergencyType = emergencyType; }
        
        public String getPlanContent() { return planContent; }
        public void setPlanContent(String planContent) { this.planContent = planContent; }
        
        public String getProcedures() { return procedures; }
        public void setProcedures(String procedures) { this.procedures = procedures; }
        
        public String getResourceRequirements() { return resourceRequirements; }
        public void setResourceRequirements(String resourceRequirements) { this.resourceRequirements = resourceRequirements; }
        
        public Integer getPriority() { return priority; }
        public void setPriority(Integer priority) { this.priority = priority; }
        
        public Integer getStatus() { return status; }
        public void setStatus(Integer status) { this.status = status; }
    }
    
    /**
     * 应急联系人
     */
    class EmergencyContact extends BaseEntity {
        private Long userId;
        private String contactName;
        private String contactPhone;
        private String relationship;
        private Integer priority;
        private Integer status;
        
        // getter/setter methods
        public Long getUserId() { return userId; }
        public void setUserId(Long userId) { this.userId = userId; }
        
        public String getContactName() { return contactName; }
        public void setContactName(String contactName) { this.contactName = contactName; }
        
        public String getContactPhone() { return contactPhone; }
        public void setContactPhone(String contactPhone) { this.contactPhone = contactPhone; }
        
        public String getRelationship() { return relationship; }
        public void setRelationship(String relationship) { this.relationship = relationship; }
        
        public Integer getPriority() { return priority; }
        public void setPriority(Integer priority) { this.priority = priority; }
        
        public Integer getStatus() { return status; }
        public void setStatus(Integer status) { this.status = status; }
    }
    
    /**
     * 应急资源
     */
    class EmergencyResource extends BaseEntity {
        private String resourceCode;
        private String resourceName;
        private String resourceType;
        private Long communityId;
        private Integer quantity;
        private Integer availableQuantity;
        private Integer status;
        
        // getter/setter methods
        public String getResourceCode() { return resourceCode; }
        public void setResourceCode(String resourceCode) { this.resourceCode = resourceCode; }
        
        public String getResourceName() { return resourceName; }
        public void setResourceName(String resourceName) { this.resourceName = resourceName; }
        
        public String getResourceType() { return resourceType; }
        public void setResourceType(String resourceType) { this.resourceType = resourceType; }
        
        public Long getCommunityId() { return communityId; }
        public void setCommunityId(Long communityId) { this.communityId = communityId; }
        
        public Integer getQuantity() { return quantity; }
        public void setQuantity(Integer quantity) { this.quantity = quantity; }
        
        public Integer getAvailableQuantity() { return availableQuantity; }
        public void setAvailableQuantity(Integer availableQuantity) { this.availableQuantity = availableQuantity; }
        
        public Integer getStatus() { return status; }
        public void setStatus(Integer status) { this.status = status; }
    }
    
    /**
     * 紧急求助统计
     */
    class EmergencyStatistics {
        private Integer totalCalls;
        private Integer pendingCalls;
        private Integer processingCalls;
        private Integer completedCalls;
        private Integer totalContacts;
        private Integer totalResources;
        private Double averageResponseTime;
        private Double completionRate;
        
        // getter/setter methods
        public Integer getTotalCalls() { return totalCalls; }
        public void setTotalCalls(Integer totalCalls) { this.totalCalls = totalCalls; }
        
        public Integer getPendingCalls() { return pendingCalls; }
        public void setPendingCalls(Integer pendingCalls) { this.pendingCalls = pendingCalls; }
        
        public Integer getProcessingCalls() { return processingCalls; }
        public void setProcessingCalls(Integer processingCalls) { this.processingCalls = processingCalls; }
        
        public Integer getCompletedCalls() { return completedCalls; }
        public void setCompletedCalls(Integer completedCalls) { this.completedCalls = completedCalls; }
        
        public Integer getTotalContacts() { return totalContacts; }
        public void setTotalContacts(Integer totalContacts) { this.totalContacts = totalContacts; }
        
        public Integer getTotalResources() { return totalResources; }
        public void setTotalResources(Integer totalResources) { this.totalResources = totalResources; }
        
        public Double getAverageResponseTime() { return averageResponseTime; }
        public void setAverageResponseTime(Double averageResponseTime) { this.averageResponseTime = averageResponseTime; }
        
        public Double getCompletionRate() { return completionRate; }
        public void setCompletionRate(Double completionRate) { this.completionRate = completionRate; }
    }
}
